﻿#include "iostateui.h"

IoStateUi::IoStateUi(QWidget* parent)
    : QWidget(parent),
      off_pic_(QPixmap(QString::fromUtf8(":/pic/src/led/black_led.png"))),
      on_pic_(QPixmap(QString::fromUtf8(":/pic/src/led/yellow_led.png"))),
      cur_module_index_(0),
      io_type_(10, false)  //预先设置10个长度，5个模块
{
  read_io_num = 32 * 2;  //初始化--需要读取的io的数目
  readIoDefineFile();    // first thing's first

  //  this->resize(380, 560);
  //  this->setGeometry(QRect(0, 0, 380, 560));

  //这里设置了模块,可以在这里增加
  //设置combo box
  QComboBox* combo_box = new QComboBox(this);
  combo_box->setFont(QFont("微软雅黑", 14));
  combo_box->setStyleSheet("QComboBox{background-color:rgb(209, 209, 209); color: black;}");
  QStringList items;  //初始化--32位一个栏目
  items << "输入IO点-32位"
        << "输出IO点-32位";
  combo_box->addItems(items);
  combo_box->setCurrentIndex(cur_module_index_);
  connect(combo_box, SIGNAL(currentIndexChanged(int)), this, SLOT(sltChangeIoModule(int)));

  total_layout_ = new QVBoxLayout(this);
  io_layout_ = new QHBoxLayout();
  left_layout_ = new QVBoxLayout();
  right_layout_ = new QVBoxLayout();

  io_layout_->addLayout(left_layout_);
  //加一个Item，然后在Item里面增加一个弹簧
  io_layout_->addItem(new QSpacerItem(51, 25, QSizePolicy::Expanding, QSizePolicy::Minimum));
  io_layout_->addLayout(right_layout_);

  total_layout_->addWidget(combo_box);
  total_layout_->addLayout(io_layout_);

  signal_mapper_ = new QSignalMapper(this);  //用于button的信号连接
  for (int i = 0; i < 32; ++i) {
    //设置label样式
    QLabel* label = new QLabel;
    label->setPixmap(off_pic_);
    label->setScaledContents(true);  //自动调整图片
    label->setMaximumSize(32, 32);

    //设置button样式
    QPushButton* button = new QPushButton(this);

    if (io_name_list_.at(i).isEmpty()) {
      button->setText("undefined");
    } else {
      button->setText(io_name_list_.at(i));
    }
    button->setFont(QFont("微软雅黑", 10));
    button->setMinimumSize(500, 32);
    button->setMaximumSize(500, 32);
    button->setStyleSheet("QPushButton{background-color: rgb(0, 198, 198); color: black;}");
    //设置layout,label和button为一组
    item_layout_ = new QHBoxLayout;
    item_layout_->addWidget(label);
    item_layout_->addWidget(button);
    if (i < 16) {
      left_layout_->addLayout(item_layout_);
    } else {
      right_layout_->addLayout(item_layout_);
    }

    label_list_.append(label);
    button_list_.append(button);

    //设置signal mapper
    signal_mapper_->setMapping(button, i);
    connect(button, SIGNAL(clicked()), signal_mapper_, SLOT(map()));
  }

  connect(signal_mapper_, SIGNAL(mapped(int)), this, SLOT(sltToggleDo(int)));
}

/**
 * @brief IoStateUi::sltChangeIoModule 传入要显示的模块
 * @param index
 */
void IoStateUi::sltChangeIoModule(int index) {
  cur_module_index_ = index;
  //每次切换模块都要重新显示name和type
  setIoName();
  setIoType();
}

/**
 * @brief IoStateUi::readIoDefineFile 从ini文件中读取io口的名称
 */
void IoStateUi::readIoDefineFile() {
  QString file_name("./ini/iodefine.ini");
  QSettings setting(file_name, QSettings::IniFormat);

  setting.setIniCodec(QTextCodec::codecForName("UTF-8"));

  if (QFile::exists(file_name)) {
    for (int i = 0; i < read_io_num; ++i) {
      QString raw_string = setting.value(QString::number(i), "").toString();
      io_name_list_ << raw_string;
    }
  }
  //不存在则创建空文件
  else {
    for (int i = 0; i < read_io_num; ++i) {
      setting.setValue(QString::number(i), "");
      io_name_list_ << "undefine";
    }
    qCritical() << "不存在iodefine.ini文件";
  }
}

/**
 * @brief IoStateUi::setIotype 设置IO的type， DI只可读取， DO可以操作。
 * @param
 */
void IoStateUi::setIoType() {
  for (int i = 0; i < 32; i++) {
    int io_index = i + cur_module_index_ * 32;
    auto button = button_list_.at(i);
    //如果是do,设置点击信号槽
    if ((io_type_.testBit(cur_module_index_ * 2) && (i < 16)) || (io_type_.testBit(cur_module_index_ * 2 + 1) && (i >= 16))) {
      button->setDisabled(false);
      signal_mapper_->setMapping(button, io_index);
    } else {
      button->setDisabled(true);
    }
  }
}

/**
 * @brief IoStateUi::setIoName 设置IO名称
 * @param
 */
void IoStateUi::setIoName() {
  for (int i = 32 * cur_module_index_; i < 32 * (cur_module_index_ + 1); ++i) {
    auto button = button_list_.at(i % 32);
    auto name = io_name_list_.at(i);
    auto label = label_list_.at(i % 32);
    label->setPixmap(off_pic_);
    if (name.isEmpty()) {
      button->setText("undefined");
    } else {
      button->setText(name);
    }
  }
}

/**
 * @brief IoStateUi::sltToggleDo 把模块id和io口id组合传出去
 * @param id
 */
void IoStateUi::sltToggleDo(int id) { emit sigToggleDoBit(cur_module_index_, id); }

/**
 * @brief IoStateUi::sltSetIoType 传入ioType
 * @param ioType
 */
void IoStateUi::sltSetIoType(const QBitArray& ioType) {
  io_type_ = ioType;
  //先进行一次初始化，不然直接点开io界面发现没有设置iotype
  setIoType();
}

// IoStateUi::~IoStateUi() = default;

/**
 * @brief IoState::slotRecvIoData 槽函数,接收端子板和扩展io的状态,并显示相对应的图标
 * @param ioState io数据
 */
void IoStateUi::slotRecvIoData(const QBitArray& ioState) {
  for (int j = 0; j < 32; j++) {
    int id = cur_module_index_ * 32 + j;
    if (ioState.testBit(id)) {
      label_list_.at(j)->setPixmap(on_pic_);
    } else {
      label_list_.at(j)->setPixmap(off_pic_);
    }
  }
}
